package com.guoqi.clickevent

import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.AccessibilityServiceInfo
import android.accessibilityservice.GestureDescription
import android.annotation.TargetApi
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Path
import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.SystemClock
import android.support.annotation.RequiresApi
import android.util.Log
import android.view.KeyEvent
import android.view.MotionEvent
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityManager
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Toast


/**
 * 继承自无障碍服务
 *
 *
 * <p>
 * 在配置好AccessibilityService后，而且系统“辅助设置”已打开配置过的AccessibilityService，刚开始能用，但莫名出现onAccessibilityEvent事件接收不到的情况，原因只有一条：
 * 程序出现了ANR，崩溃后AccessibilityServices就失效了，重启手机即可
 * </p>
 */
class ClickService : AccessibilityService() {

    private var receiver: ClickReceiver? = null


    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        //接收事件,如触发了通知栏变化、界面变化等
        when (event.eventType) {
            //界面点击
            AccessibilityEvent.TYPE_VIEW_CLICKED -> {
            }
            //界面文字改动
            AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED -> {
            }

        }
    }

    override fun onKeyEvent(event: KeyEvent): Boolean {
        Log.e(TAG, "按钮点击变化")

        //接收按键事件
        return super.onKeyEvent(event)
    }

    override fun onInterrupt() {
        Log.e(TAG, "授权中断")
        //服务中断，如授权关闭或者将服务杀死
    }

    override fun onServiceConnected() {
        super.onServiceConnected()
        Log.e(TAG, "service授权成功")
        service = this
        //连接服务后,一般是在授权成功后会接收到
        if (receiver == null) {
            receiver = ClickReceiver()
            val intentFilter = IntentFilter()
            intentFilter.addAction("qukan_auto_browser")
            registerReceiver(receiver, intentFilter)
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(receiver)
    }


    //执行点击
    private fun performClick(resourceId: String) {
        Log.e(TAG, "执行点击: $resourceId")
        try {
            val nodeInfo = this.rootInActiveWindow
            var targetNode: AccessibilityNodeInfo? = null
            //通过名字获取
            //targetNode = findNodeInfosByText(nodeInfo,"广告");
            //通过id获取
            targetNode = findNodeInfosById(nodeInfo, "$targetPackageName:id/$resourceId")
            if (targetNode != null && targetNode!!.isClickable) {
                targetNode.performAction(AccessibilityNodeInfo.ACTION_CLICK)
            } else {
                Toast.makeText(application, "未找到点击事件绑定的$resourceId", Toast.LENGTH_SHORT).show()
            }
        } catch (e: Exception) {
            Log.e(TAG, "Exception:" + e.message)
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    private fun performFling(resourceId: String) {
        Log.e(TAG, "执行滑动: $resourceId")
        try {
            val nodeInfo = this.rootInActiveWindow
            val outBounds = Rect()
            nodeInfo.getBoundsInScreen(outBounds)
            var right = outBounds.right
            var left = outBounds.left
            var top = outBounds.top
            var bottom = outBounds.bottom
            var centerX = outBounds.centerX()
            var centerY = outBounds.centerY()
            //Log.e(TAG, "top:${top},right:${right},bottom:${bottom},left:${left},centerX:${centerX},centerY:${centerY},")

            val downTime = SystemClock.currentThreadTimeMillis()
            val down = MotionEvent.obtain(downTime, SystemClock.currentThreadTimeMillis(), MotionEvent.ACTION_DOWN, 400f, 100f, 0)
            SystemClock.sleep(50)
            val move = MotionEvent.obtain(downTime, SystemClock.currentThreadTimeMillis(), MotionEvent.ACTION_MOVE, 50f, 220f, 0)
            SystemClock.sleep(50)
            val up = MotionEvent.obtain(downTime, SystemClock.currentThreadTimeMillis(), MotionEvent.ACTION_UP, 50f, 220f, 0)

            var targetNode: AccessibilityNodeInfo? = null
            //通过名字获取
            //targetNode = findNodeInfosByText(nodeInfo,"广告");
            //通过id获取
            targetNode = findNodeInfosById(nodeInfo, "$targetPackageName:id/$resourceId")
            if (targetNode != null) {
//                val arguments = Bundle()
//                arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT, AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE)
//                arguments.putBoolean(AccessibilityNodeInfo.ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN,false)
//                targetNode.performAction(AccessibilityAction.ACTION_NEXT_AT_MOVEMENT_GRANULARITY.id,arguments)
                val arguments = Bundle()
                arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_X, 200)
//                targetNode.performAction(AccessibilityAction.ACTION_NEXT_AT_MOVEMENT_GRANULARITY.id, arguments)
                targetNode.performAction(AccessibilityNodeInfo.ACTION_CLICK)
                Handler().postDelayed({ performFling(resourceId) }, 5000)
            } else {
                Toast.makeText(application, "未找到点击事件绑定的$resourceId", Toast.LENGTH_SHORT).show()
                Handler().postDelayed({ performFling(resourceId) }, 5000)
            }
        } catch (e: Exception) {
            Log.e(TAG, "Exception:" + e.message)
        }
    }


    inner class ClickReceiver : BroadcastReceiver() {

        override fun onReceive(context: Context, intent: Intent) {
            Log.e(TAG, "======开始自动执行======")
            //先刷新新闻
            //performClick("ik")

            //滑动屏幕
            //performFling("image")

        }

    }

    companion object {
        val TAG = "ClickService"
        var service: ClickService? = null
        var targetPackageName = ""

        /**
         * 通过id查找
         */
        fun findNodeInfosById(nodeInfo: AccessibilityNodeInfo, resId: String): AccessibilityNodeInfo? {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                val list = nodeInfo.findAccessibilityNodeInfosByViewId(resId)
                if (list != null && !list.isEmpty()) {
                    return list[0]
                }
            }
            return null
        }

        /**
         * 通过文本查找
         */
        fun findNodeInfosByText(nodeInfo: AccessibilityNodeInfo, text: String): AccessibilityNodeInfo? {
            val list = nodeInfo.findAccessibilityNodeInfosByText(text)
            return if (list == null || list.isEmpty()) {
                null
            } else list[0]
        }

        /**
         * 判断当前服务是否正在运行
         */
        val isRunning: Boolean
            get() {
                if (service == null) {
                    return false
                }
                val accessibilityManager = service!!.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
                val info = service!!.serviceInfo ?: return false
                val list = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC)
                val iterator = list.iterator()

                var isConnect = false
                while (iterator.hasNext()) {
                    val i = iterator.next()
                    if (i.id == info.id) {
                        isConnect = true
                        break
                    }
                }
                return isConnect
            }

        /**
         * 执行返回
         */
        fun performBack() {
            Log.e(TAG, "执行返回")
            service?.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK)
        }

        /**
         * 立即发送移动的手势
         * 注意7.0以上的手机才有此方法，请确保运行在7.0手机上
         *
         * @param path  移动路径
         * @param mills 持续总时间
         */
        @RequiresApi(24)
        fun dispatchGestureMove(path: Path, mills: Long) {
            service?.dispatchGesture(GestureDescription.Builder().addStroke(GestureDescription.StrokeDescription(path, 0, mills)).build(), null, null)
        }

        /**
         * 点击指定位置
         * 注意7.0以上的手机才有此方法，请确保运行在7.0手机上
         */
        @RequiresApi(24)
        fun dispatchGestureClick(x: Float, y: Float) {
            val path = Path()
            path.moveTo(x, y)
            service?.dispatchGesture(GestureDescription.Builder().addStroke(GestureDescription.StrokeDescription(path, 0, 100)).build(), null, null)
        }
    }


    private val listViewClassName = "android.widget.ListView"
    /**根据固定的类名循环查找到listView,查找到目标listView后即退出循环
     * @param node
     * @return
     */
    fun recycleFindListView(node: AccessibilityNodeInfo): AccessibilityNodeInfo? {
        if (node.childCount == 0) {
            return null
        } else {//listview下面必定有子元素，所以放在此时判断
            for (i in 0 until node.childCount) {
                if (listViewClassName == node.className) {
                    Log.d(TAG, "查找到listview了。。。")
                    return node
                } else if (node.getChild(i) != null) {
                    val result = recycleFindListView(node.getChild(i))
                    return result ?: continue
                }
            }
        }
        return null
    }

    override fun onUnbind(intent: Intent?): Boolean {
        service = null
        return super.onUnbind(intent)
    }


}
